package com.ikingtech.platform.service.system.user.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.cache.constants.CacheConstants;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.enums.system.user.UserConfigTypeEnum;
import com.ikingtech.framework.sdk.log.embedded.annotation.OperationLog;
import com.ikingtech.framework.sdk.user.model.UserConfigDTO;
import com.ikingtech.framework.sdk.user.model.UserConfigInfoDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.framework.sdk.web.annotation.PostRequest;
import com.ikingtech.platform.service.system.user.entity.UserConfigDO;
import com.ikingtech.platform.service.system.user.service.repository.UserConfigRepository;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Map;

/**
 * 用户管理模块
 *
 * @author tie yan
 */
@RequiredArgsConstructor
@ApiController(value = "/system/user/config", name = "系统管理-用户配置管理", description = "系统管理-用户配置管理")
public class UserConfigController {

    private final UserConfigRepository repo;

    private final StringRedisTemplate redisTemplate;

    @OperationLog(value = "更新用户配置")
    @PostRequest(order = 1, value = "/update", summary = "更新用户配置信息", description = "更新用户配置信息")
    public R<Object> updateConfig(@Parameter(name = "userConfigDTO", description = "配置信息")
                                  @RequestBody UserConfigDTO userConfig) {
        List<UserConfigInfoDTO> configs = userConfig.getConfigInfoList();
        String userId = Boolean.TRUE.equals(userConfig.getGlobal()) ? "global" : userConfig.getUserId();
        List<UserConfigDO> entities = this.repo.list(Wrappers.<UserConfigDO>lambdaQuery()
                .eq(UserConfigDO::getUserId, userId)
                .and(Tools.Str.isBlank(Me.tenantCode()), wrapper ->
                        wrapper
                                .isNull(UserConfigDO::getTenantCode)
                                .or()
                                .eq(Tools.Str.isBlank(Me.tenantCode()), UserConfigDO::getTenantCode, Tools.Str.EMPTY))
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserConfigDO::getTenantCode, Me.tenantCode()));
        Map<String, UserConfigDO> configMap = Tools.Coll.convertMap(entities, UserConfigDO::getType, entity -> entity);
        List<UserConfigDO> newEntities = Tools.Coll.convertList(configs, config -> {
            UserConfigDO newEntity = configMap.computeIfAbsent(config.getType().name(), t -> {
                UserConfigDO entity = new UserConfigDO();
                entity.setId(Tools.Id.uuid());
                return entity;
            });
            newEntity.setType(config.getType().name());
            newEntity.setUserId(userId);
            newEntity.setValue(config.getValue());
            newEntity.setGlobal(userConfig.getGlobal());
            newEntity.setTenantCode(Me.tenantCode());
            return newEntity;
        });
        if (Tools.Coll.isNotBlank(newEntities)) {
            this.repo.saveOrUpdateBatch(newEntities);
            this.redisTemplate.opsForHash().putAll(CacheConstants.userConfigFormat(userConfig.getUserId(), Me.tenantCode()), Tools.Coll.convertMap(newEntities, UserConfigDO::getType, UserConfigDO::getValue));
        }
        return R.ok();
    }

    @PostRequest(order = 2, value = "/list/login-user", summary = "获取登录用户配置信息", description = "获取登录用户配置信息")
    public R<UserConfigDTO> listConfigByLoginUser(@Parameter(name = "global", description = "是否为全局配置")
                                                  @RequestParam(value = "global", required = false) Boolean global) {
        String userId = Boolean.TRUE.equals(global) ? "global" : Me.id();
        List<UserConfigDO> entities = this.repo.list(Wrappers.<UserConfigDO>lambdaQuery()
                .eq(UserConfigDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserConfigDO::getTenantCode, Me.tenantCode()));
        if (Tools.Coll.isBlank(entities)) {
            return R.ok();
        }
        UserConfigDTO result = new UserConfigDTO();
        result.setUserId(userId);
        result.setGlobal(Boolean.TRUE.equals(global));
        result.setConfigInfoList(Tools.Coll.convertList(entities, entity -> Tools.Bean.copy(entity, UserConfigInfoDTO.class)));
        return R.ok(result);
    }

    @PostRequest(order = 3, value = "/front-gray-scale/value", summary = "获取前端灰度值", description = "获取前端灰度值")
    public R<String> getFrontGrayScale() {
        return R.ok(this.repo.getObj(Wrappers.<UserConfigDO>lambdaQuery()
                .select(UserConfigDO::getValue)
                .eq(UserConfigDO::getUserId, "global")
                .eq(UserConfigDO::getType, UserConfigTypeEnum.FRONT_GRAY_SCALE.name()), String.class::cast));
    }
}
